package com.iot.ht.controller.htuser.service;

import com.iot.core.data.BaseQto;
import com.iot.core.data.IdNameDto;
import com.iot.core.data.entity.HtUser;
import com.iot.core.data.entity.HtUserDept;
import com.iot.core.data.entity.HtUserRole;
import com.iot.core.data.mapper.HtDbMapper;
import com.iot.core.data.mapper.HtUserDeptMapper;
import com.iot.core.data.mapper.HtUserMapper;
import com.iot.core.data.mapper.HtUserRoleMapper;
import com.iot.core.data.service.IHtUserRoleService;
import com.iot.core.data.service.ServiceImpl;
import com.iot.core.exception.MyException;
import com.iot.core.manager.auth.AuthManager;
import com.iot.core.springboot.MyThreadLocal;
import com.iot.core.util.StreamUtil;
import com.iot.ht.controller.htuser.data.HtUserDetailQto;
import com.iot.ht.controller.htuser.data.HtUserDto;
import com.iot.ht.controller.htuser.data.HtUserQto;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.stream.Collectors;

import static com.iot.core.data.entity.table.HtDeptTableDef.HT_DEPT;
import static com.iot.core.data.entity.table.HtUserDeptTableDef.HT_USER_DEPT;
import static com.iot.core.data.entity.table.HtUserRoleTableDef.HT_USER_ROLE;
import static com.iot.core.data.entity.table.HtUserTableDef.HT_USER;

@Slf4j
@Service
public class HtUserService extends ServiceImpl<HtUserMapper, HtUser> implements IHtUserService {
    @Autowired
    HtDbMapper htdbMapper;
    @Autowired
    IHtUserRoleService iHtUserRoleService;


    @Autowired
    HtUserDeptMapper htUserDeptMapper;
    @Autowired
    HtUserRoleMapper htUserRoleMapper;

    @Override

    public Page<HtUserDto> page(HtUserQto qm){
        var qw=QueryWrapper.create();
        qw.select(HT_USER.ALL_COLUMNS)

           .select(HT_DEPT.NAME.as("crtDname"))
                .select(HT_USER_DEPT.STATE)
                .from(HT_USER_DEPT).as("ud")
                .innerJoin(HT_USER).as("a")
                    .on(HT_USER_DEPT.HTDEPT_ID.eq(qm.getHtdeptId())
                            .and(HT_USER_DEPT.HTUSER_ID.eq(HT_USER.ID))
                    )
                .innerJoin(HT_DEPT)
                    .on(HT_USER_DEPT.HTDEPT_ID.eq(HT_DEPT.ID))
                ;


        if(StringUtils.hasText(qm.getState() )){
            qw.and( HT_USER_DEPT.STATE.eq(qm.getState()));
        }else{

        }


        if(StringUtils.hasText(qm.getKey() )){
            qw.and( HT_USER.NAME.like(qm.getKey())
                            .or( HT_USER.ENAME.like(qm.getKey()) )
                    .or( HT_USER.MOBILE.like(qm.getKey()) )
            );

        }
        var sort=qm.getSort();
        qw.orderBy( sort.toString()  );

        var r=getMapper().pageAs( qm,qw,HtUserDto.class);
        var luid=r.getRecords().stream().map(a->a.getId()).distinct().collect(Collectors.toList());
        var lrole=iHtUserRoleService.getRoles(luid,qm.getHtdeptId());
        for(var mm:r.getRecords()){
            mm.setPwd("");
            mm.setCrtDid(qm.getHtdeptId() );
            mm.getRoleList().clear();
            var mr= StreamUtil.get(lrole, a->a.getId1().equals(mm.getId()));
            if(!ObjectUtils.isEmpty(mr)){
                var min=new IdNameDto();
                min.setId(mr.getId());
                min.setName(mr.getName());
                mm.getRoleList().add(min);
            }

        }

        return r;
    }

    @Override
    public HtUserDto detail(HtUserDetailQto qm) {
        var m=getById(qm.getId());
        var mm=new HtUserDto();
        getMapper().entityToDto(m,mm);
        mm.setCrtDid(qm.getHtdeptId());
        mm.setCrtDname(htdbMapper.getName("htdept",mm.getCrtDid() ));
        var luid=new ArrayList<Long>();
        luid.add(mm.getId() );
        var lrole=iHtUserRoleService.getRoles( mm.getId(),qm.getHtdeptId());
        mm.getRoleList().addAll(lrole);
        return mm;
    }

    @Override
    public HtUserDto InsertInit(BaseQto qm) {
        var mm=new HtUserDto();
        mm.setId(htdbMapper.nextLong() );
        mm.setCrtDid(qm.getId() );
        mm.setCrtDname( htdbMapper.getName("htdept",mm.getCrtDid()  ));
        return mm;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(HtUserDto mm) {
        var qw=new QueryWrapper();
        qw.and(HT_USER.ENAME.eq(mm.getEname() ) );
        var mold=getMapper().selectOneByQuery(qw);
        if(!ObjectUtils.isEmpty(mold)){
            throw new MyException("账号重复");
        }
        var m = new  HtUser();
        getMapper().dtoToEntity(mm,m);
        m.setPwd(AuthManager.getInstance().createPwd(mm.getEname(),mm.getPwd() ));

        var mdept=new HtUserDept();
        mdept.setId(htdbMapper.nextLong() );
        mdept.setHtuserId(m.getId() );
        mdept.setHtdeptId(mm.getCrtDid() );
        htUserDeptMapper.insert(mdept );

        for(var mr:mm.getRoleList()){
            var mrm=new HtUserRole();
            mrm.setId(htdbMapper.nextLong() );
            mrm.setHtuserId(m.getId() );
            mrm.setHtdeptId(mm.getCrtDid() );
            mrm.setHtroleId(mr.getId());
            htUserRoleMapper.insert(mrm);
        }
        return  insert(m );
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(HtUserDto mm) {
        var m=getById(mm.getId());
        if(!m.getEname().equals(mm.getEname())){
            var qw=new QueryWrapper();
            qw.and(HT_USER.ENAME.eq(mm.getEname() ) );
            var mold=getMapper().selectOneByQuery(qw);
            if(!ObjectUtils.isEmpty(mold)){
                throw new MyException("账号重复");
            }
        }
        getBaseMapper().dtoToEntity(mm,m);
        if(mm.isEditPwd()){
            m.setPwd(AuthManager.getInstance().createPwd(mm.getEname(),mm.getPwd() ));
        }

        var qwur=htUserRoleMapper.getQueryWrapper();
        qwur.and(HT_USER_ROLE.HTUSER_ID.eq(m.getId() ));
        qwur.and(HT_USER_ROLE.HTDEPT_ID.eq(m.getCrtDid()));
        qwur.orderBy(HT_USER_ROLE.ID,true );
        var loldr=htUserRoleMapper.selectListByQuery(qwur);
        for(var masrc:mm.getRoleList()){
            var mrm = StreamUtil.get(loldr,a->a.getHtroleId().equals(masrc.getId()));

            if (mrm == null)
            {
                mrm=new HtUserRole();
                mrm.setId(htdbMapper.nextLong() );
                mrm.setHtuserId(m.getId() );
                mrm.setHtdeptId(mm.getCrtDid() );
                mrm.setHtroleId(masrc.getId());
                htUserRoleMapper.insert(mrm,true);
            }

        }

        for(var madb : loldr)
        {
            var masrc= StreamUtil.get(  mm.getRoleList(), a->a.getId().equals( madb.getHtroleId()) );
            if (masrc == null)
            {
                htUserRoleMapper.deleteById(madb,true);
            }
        }

        return  updateById(m);
    }

    @Override
    public int qy(BaseQto mm) {
        var muser=getById(mm);
        var su= MyThreadLocal.get().getSu();
        var qw=htUserDeptMapper.getQueryWrapper();
        qw.and(HT_USER_DEPT.HTUSER_ID.eq(muser.getId() ));
        qw.and(HT_USER_DEPT.HTDEPT_ID.eq(muser.getCrtDid()));
        var m=htUserDeptMapper.selectOneByQuery(qw);
        m.setState("启用");
        MyThreadLocal.get().setLogMemo("启用用户:"+muser.getName() );
        return htUserDeptMapper.updateById(m,true);
    }

    @Override
    public int ty(BaseQto mm) {
        var muser=getById(mm);
        var su= MyThreadLocal.get().getSu();
        var qw=htUserDeptMapper.getQueryWrapper();
        qw.and(HT_USER_DEPT.HTUSER_ID.eq(muser.getId() ));
        qw.and(HT_USER_DEPT.HTDEPT_ID.eq(muser.getCrtDid()));
        var m=htUserDeptMapper.selectOneByQuery(qw);
        m.setState("停用");
        MyThreadLocal.get().setLogMemo("停用用户:"+muser.getName() );
        return htUserDeptMapper.updateById(m,true);
    }

}
